#include "common.h"
#include "..\wow6mapper\wow6mapper\ChunkHeader.h"
#include "mverchunk.h"
#include "wmogroup.h"
#include "log.h"

extern Log *pLog;
//------------------------------------------------------------------------------
WmoGroup::WmoGroup( BufferS_t &grp_buf ) {
  // create an istream of our buffer
  std::stringbuf str_buf( grp_buf );
  std::istream i_str( &str_buf );

  std::streamoff chunk_start = i_str.tellg();
  std::streamoff cur_pos = chunk_start;
  ChunkHeader_s header;

  uint32_t size = grp_buf.size();
  while (cur_pos < size)
  {
	  i_str.read((char *)&header, sizeof(ChunkHeader_s));
	  i_str.seekg(cur_pos, std::ios::beg);								  // need to rewind the stream 
	
	  if (checkChunkId((char *)&header, "MVER"))
	  {
		  i_str.read((char*)&_mverChunk, sizeof(MverChunk_s));
	  }
	  else  if (checkChunkId((char *)&header, "MOGP"))
	  {
		  i_str.read((char*)&_mogpChunk, sizeof(MogpChunk_s));
	  }
	  else  if (checkChunkId((char *)&header, "MOPY"))
	  {
		  i_str.read((char*)&_mopyChunk, sizeof(ChunkHeader_s));

		  if (_mopyChunk.size) {
			  _mopyChunk.infos.resize(_mopyChunk.size / sizeof(MopyChunk_s::MaterialInformation_s));
			  i_str.read((char*)&_mopyChunk.infos[0], _mopyChunk.size);
		  }
	  }
	  else  if (checkChunkId((char *)&header, "MOVI"))
	  {
		  i_str.read((char*)&_moviChunk, sizeof(ChunkHeader_s));

		  if (_moviChunk.size) {
			  _moviChunk.indices.resize(_moviChunk.size / sizeof(uint16_t));
			  i_str.read((char*)&_moviChunk.indices[0], _moviChunk.size);
		  }
	  }
	  else  if (checkChunkId((char *)&header, "MOVT"))
	  {
		  i_str.read((char*)&_movtChunk, sizeof(ChunkHeader_s));

		  if (_movtChunk.size) {
			  _movtChunk.vertices.resize(_movtChunk.size / sizeof(glm::vec3));
			  i_str.read((char*)&_movtChunk.vertices[0], _movtChunk.size);
		  }
	  }
	  else  if (checkChunkId((char *)&header, "MONR"))
	  {
		  i_str.read((char*)&_monrChunk, sizeof(ChunkHeader_s));

		  if (_monrChunk.size) {
			  _monrChunk.normals.resize(_monrChunk.size / sizeof(glm::vec3));
			  i_str.read((char*)&_monrChunk.normals[0], _monrChunk.size);
		  }
	  }
	  else  if (checkChunkId((char *)&header, "MOTV"))
	  {
		  i_str.read((char*)&_motvChunk, sizeof(ChunkHeader_s));

		  if (_motvChunk.size) {
			  _motvChunk.texCoords.resize(_motvChunk.size / sizeof(glm::vec2));
			  i_str.read((char*)&_motvChunk.texCoords[0], _motvChunk.size);
		  }
	  }
	  else  if (checkChunkId((char *)&header, "MOBA"))
	  {
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  else  if (checkChunkId((char *)&header, "MOBS"))
	  {
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  else  if (checkChunkId((char *)&header, "MOBN"))
	  {
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  else  if (checkChunkId((char *)&header, "MOBR"))
	  {
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  else  if (checkChunkId((char *)&header, "MODR"))
	  {
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  else  if (checkChunkId((char *)&header, "MOCV"))
	  {
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  else  if (checkChunkId((char *)&header, "MOLR"))
	  {
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  else  if (checkChunkId((char *)&header, "MLIQ"))
	  {
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  else
	  {
		  // should never get here
		  pLog->Write("WMO Group unknow chunk %s", header.id);
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  cur_pos = i_str.tellg();
  }
}

//------------------------------------------------------------------------------
const MopyChunk_s& WmoGroup::getMopyChunk() const {
  return _mopyChunk;
}

//------------------------------------------------------------------------------
const MoviChunk_s& WmoGroup::getMoviChunk() const {
  return _moviChunk;
}

//------------------------------------------------------------------------------
const MovtChunk_s& WmoGroup::getMovtChunk() const {
  return _movtChunk;
}

//------------------------------------------------------------------------------
const MonrChunk_s& WmoGroup::getMonrChunk() const {
  return _monrChunk;
}

//------------------------------------------------------------------------------
const MotvChunk_s& WmoGroup::getMotvChunk() const {
  return _motvChunk;
}